package cn.jboa.service.impl;

import cn.jboa.common.Constants;
import cn.jboa.dao.CheckResultDao;
import cn.jboa.dao.ClaimVoucherDao;
import cn.jboa.dao.ClaimVoucherDetailDao;
import cn.jboa.entity.BizClaimVoucher;
import cn.jboa.entity.BizClaimVoucherDetail;
import cn.jboa.entity.SysEmployee;
import cn.jboa.service.ClaimVoucherService;
import cn.jboa.util.PaginationSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service("claimVoucherService")
public abstract class BaseClaimVoucherServiceImpl implements ClaimVoucherService {

    @Autowired
    @Qualifier("claimVoucherDao")
    private ClaimVoucherDao claimVoucherDao;

    @Autowired
    @Qualifier("claimVoucherDetailDao")
    private ClaimVoucherDetailDao claimVoucherDetailDao;

    @Autowired
    @Qualifier("checkResultDao")
    private CheckResultDao checkResultDao;

        @Override
        public void saveClaimVoucher(BizClaimVoucher claimVoucher) {
        claimVoucher.setCreateTime(new Date());
        claimVoucher.setModifyTime(claimVoucher.getCreateTime());
        claimVoucherDao.save(claimVoucher);
    }

    @Override
    public PaginationSupport<BizClaimVoucher> getClaimVoucherPage(SysEmployee emp, String status, Date startDate, Date endDate, Integer pageNo, Integer pageSize) {

        PaginationSupport<BizClaimVoucher> result = new PaginationSupport<BizClaimVoucher>();

        if (pageNo > 0)
            result.setCurrPageNo(pageNo);
        if (pageSize > 0)
            result.setPageSize(pageSize);

        // 可以使用连接查询，配合投影，需要重新定义数据传输对象
        StringBuilder hqlBuilder = new StringBuilder("");
        List<Object> values = new ArrayList<>();
        this.buildBaseHql(emp, status, startDate, endDate, hqlBuilder, values);

        int count = claimVoucherDao.getTotalCount(hqlBuilder.toString(),
                values.toArray()).intValue();
        result.setTotalCount(count);

        if (count > 0) {
            // count % pageSize == 0 ? count / pageSize : (count / pageSize) + 1
            int pageCount = (count + result.getPageSize() - 1)
                    / result.getPageSize();
            result.setTotalPageCount(pageCount);
            if (result.getCurrPageNo() > pageCount)
                result.setCurrPageNo(pageCount);

            this.addOrders(status, hqlBuilder);

            List<BizClaimVoucher> items = claimVoucherDao.findForpage(hqlBuilder.toString(),
                    result.getCurrPageNo(), result.getPageSize(),
                    values.toArray());
            result.setItems(items);
        }

        return result;

    }


    protected abstract void buildBaseHql(SysEmployee emp, String status,
                                         Date startDate, Date endDate, StringBuilder hqlBuilder, List<Object> values);

    protected abstract void addOrders(String status, StringBuilder hqlBuilder);

/*    @Override
    public PaginationSupport<BizClaimVoucher> getClaimVoucherPage(String createSn, String status, Date startDate, Date endDate, Integer pageNo, Integer pageSize) {
        PaginationSupport<BizClaimVoucher> result=new PaginationSupport<BizClaimVoucher>();

        if(pageNo>0)result.setCurrPageNo(pageNo);
        if(pageSize>0)result.setPageSize(pageSize);

        StringBuilder hqlBuilder=new StringBuilder("from BizClaimVoucher where creator.sn=?");
        List<Object> values=new ArrayList<Object>();
        values.add(createSn);
        if(status!=null&&status.length()!=0){
            hqlBuilder.append(" and status=?");
            values.add(status);
        }
        if(startDate!=null){
            hqlBuilder.append(" and createTime>=?");
            values.add(startDate);
        }

        if(endDate!=null){
            hqlBuilder.append(" and createTime<=?");
            Calendar oneDayList=Calendar.getInstance();
            oneDayList.setTime(endDate);
            oneDayList.add(Calendar.DAY_OF_MONTH,1);
            values.add(oneDayList.getTime());
        }

        int count=claimVoucherDao.getTotalCount(hqlBuilder.toString(),values.toArray()).intValue();

        result.setTotalCount(count);

        if(count>0){
            int pageCount = (count + result.getPageSize() - 1)
                    / result.getPageSize();
            result.setTotalPageCount(pageCount);
            if (result.getCurrPageNo() > pageCount)
                result.setCurrPageNo(pageCount);

            if (status == null || status.length() == 0)
                hqlBuilder.append(" order by status, createTime desc");
            else
                hqlBuilder.append(" order by createTime desc");

            List<BizClaimVoucher> items = claimVoucherDao.findForpage(hqlBuilder.toString(),
                    result.getCurrPageNo(), result.getPageSize(),
                    values.toArray());
            result.setItems(items);
        }

        return result;
    }*/

    @Override
    public BizClaimVoucher findClaimVoucherById(Long id) {
        return claimVoucherDao.get(id);
    }

    @Override
    public void updateClaimVoucher(BizClaimVoucher claimVoucher) {
            claimVoucherDetailDao.deleteByClaimVoucher(claimVoucher);
            BizClaimVoucher toUpdate=claimVoucherDao.get(claimVoucher.getId());
            toUpdate.setModifyTime(new Date());
            toUpdate.setTotalAccount(claimVoucher.getTotalAccount());
            toUpdate.setEvent(claimVoucher.getEvent());
            if (claimVoucher.getStatus().equals(Constants.CLAIMVOUCHER_SUBMITTED)){
                toUpdate.setStatus(claimVoucher.getStatus());
                toUpdate.setNextDeal(claimVoucher.getNextDeal());
            }
            toUpdate.setDetailList(claimVoucher.getDetailList());
            for (BizClaimVoucherDetail d:toUpdate.getDetailList()){
                d.setBizClaimVoucher(toUpdate);
            }
    }

    @Override
    public void deleteClaimVoucherById(BizClaimVoucher claimVoucher) {
        claimVoucherDetailDao.deleteByClaimVoucher(claimVoucher);
        checkResultDao.deleteByClaimVoucher(claimVoucher);
        claimVoucherDao.delete(claimVoucher);
    }

    public ClaimVoucherDao getClaimVoucherDao() {
        return claimVoucherDao;
    }

    public void setClaimVoucherDao(ClaimVoucherDao claimVoucherDao) {
        this.claimVoucherDao = claimVoucherDao;
    }

    public ClaimVoucherDetailDao getClaimVoucherDetailDao() {
        return claimVoucherDetailDao;
    }

    public void setClaimVoucherDetailDao(ClaimVoucherDetailDao claimVoucherDetailDao) {
        this.claimVoucherDetailDao = claimVoucherDetailDao;
    }

    public CheckResultDao getCheckResultDao() {
        return checkResultDao;
    }

    public void setCheckResultDao(CheckResultDao checkResultDao) {
        this.checkResultDao = checkResultDao;
    }
}
